//
//  SimpleRequestTool.m
//  BagerKit
//
//  Created by Bager on 2017/8/8.
//  Copyright © 2017年 Bager. All rights reserved.
//

#import "RequestTool.h"
#import "RequestManage.h"

#import <objc/runtime.h>
#import "UIImage+tool.h"
#import <AVFoundation/AVFoundation.h>

static NSString *const NotData = @"亲,暂无数据";

static NSString *const NetError = @"服务器出错了";

static NSString *const NoNetError = @"亲,联网了吗?";

@implementation RequestTool

+ (void)monitoringNetworkState:(void (^)(NSInteger))block{
    
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    [manager startMonitoring];
    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
            {
                //未知网络
                YFLog(@"[网络状态切换]--未知网络");
            }
                break;
            case AFNetworkReachabilityStatusNotReachable:
            {
                //无法联网
                YFLog(@"[网络状态切换]--无法联网");
            }
                break;
                
            case AFNetworkReachabilityStatusReachableViaWWAN:
            {
                //手机自带网络
                YFLog(@"[网络状态切换]--当前使用的是2g/3g/4g网络");
            }
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
            {
                //WIFI
                YFLog(@"[网络状态切换]--当前在WIFI网络下");
            }
                
        }
        block(status);
    }];
}
- (NSString *)baseUrl{
    return [RequestManage shareHTTPManage].baseURL.absoluteString;
}

+ (instancetype)shareManager{
    static RequestTool *shareManage = nil;
    static dispatch_once_t once;
    dispatch_once(&once,^{
        shareManage = [[RequestTool alloc] init];
    });
    return shareManage;
}

- (void)sendRequestWithAPI:(NSString *)requestAPI
                withParams:(NSDictionary *)params
               loadingView:(UIView *)loadingView
             responseBlock:(RequestResponse)response
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    //修改为GBK编码
    [RequestManage shareHTTPManage].requestSerializer.stringEncoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    //不处理cookie
    [RequestManage shareHTTPManage].requestSerializer.HTTPShouldHandleCookies = NO;
    
    NSString *baseUrl = [RequestManage shareHTTPManage].baseURL.absoluteString;
    //请求
    YFLog(@"\nRequest=====>URL:%@%@\nparams:%@",baseUrl,requestAPI,params);

    DefineWeakSelf;
    
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];

    if (loadingView)
    {
        [MBProgressHUD showHUDAddedTo:loadingView animated:YES];
    }

    [[RequestManage shareHTTPManage] POST:requestAPI parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

        if (loadingView)
        {
            [MBProgressHUD hideHUDForView:loadingView animated:YES];
        }

        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        //响应
        
        NSData *data = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:nil];
        
        NSString *jsonStr=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        
        YFLog(@"\nResponse=====>URL:%@%@\nresult:%@",baseUrl,requestAPI,jsonStr);
        
        NSDictionary *dict = responseObject;
        if ([[dict objectForKey:@"errorCode"] integerValue] == 0)
        {
            response(responseObject, NO, nil, 0);
        }
        else
        {
            [weakSelf hideRefreshWithView:loadingView];
            [Toast alertViewWithMsg:[dict objectForKey:@"errorStr"]?:NetError view:window];
        }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        if (loadingView)
        {
            [MBProgressHUD hideHUDForView:loadingView animated:YES];
        }
        
        [weakSelf hideRefreshWithView:loadingView];
        
        [Toast alertViewWithMsg:NoNetError view:window];
    }];
}

- (void)hideRefreshWithView:(UIView *)view
{
    for (UIView *sView in view.subviews)
    {
        if ([sView isKindOfClass:[UITableView class]])
        {
            UITableView *tempTable = (UITableView *)sView;
            [tempTable.mj_header endRefreshing];
            [tempTable.mj_footer endRefreshing];
        }
    }
}

- (void)sendGetRequestWithAPI:(NSString *)requestAPI
                withParams:(NSDictionary *)params
               loadingView:(UIView *)loadingView
             responseBlock:(RequestResponse)response
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    //修改为GBK编码
    [RequestManage shareHTTPManage].requestSerializer.stringEncoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    //不处理cookie
    [RequestManage shareHTTPManage].requestSerializer.HTTPShouldHandleCookies = NO;
    
    NSString *baseUrl = [RequestManage shareHTTPManage].baseURL.absoluteString;
    //请求
    YFLog(@"\nRequest=====>URL:%@%@\nparams:%@",baseUrl,requestAPI,params);
    
    
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    
    [MBProgressHUD showHUDAddedTo:loadingView animated:YES];
    
    [[RequestManage shareHTTPManage] GET:requestAPI parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        [MBProgressHUD hideHUDForView:loadingView animated:YES];
        
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        //响应
        YFLog(@"\nResponse=====>URL:%@%@\nresult:%@",baseUrl,requestAPI,responseObject);
        
        NSDictionary *dict = responseObject;
        if ([[dict objectForKey:@"errorCode"] integerValue] == 0)
        {
            response(responseObject, NO, nil, 0);
        }
        else
        {
            [Toast alertViewWithMsg:[dict objectForKey:@"errorStr"]?:NetError view:window];
        }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        [MBProgressHUD hideHUDForView:loadingView animated:YES];
        
        [Toast alertViewWithMsg:NoNetError view:window];
        
    }];
    
}


#pragma mark [下载和上传]
//- (NSArray *)finishTasks{
//    
//    NSArray *array = (NSArray *)[[UserInfoModel sharedManage]getObjWithKey:@"finishTasks"];
//    if (array) {
//        return array;
//    }
//    return [NSArray array];
//}
//
//- (void)setFinishTasks:(NSArray *)finishTasks{
//    
//    [[UserInfoModel sharedManage]saveObjWithKey:@"finishTasks" andValue:finishTasks];
//}
//
//- (NSArray *)taskList{
//    
//    NSArray *array = (NSArray *)[[UserInfoModel sharedManage]getObjWithKey:@"taskList"];
//    if (array) {
//        return array;
//    }
//    return [NSArray array];
//}
//- (void)setTaskList:(NSArray *)taskList{
//    
////    [[UserInfoModel sharedManage]saveObjWithKey:@"taskList" andValue:taskList];
//}


- (void)createDownloadTaskWithURL:(NSString *)url
                      withFileName:(NSString *)fileName
                              Task:(DownloadTask)downloadTask
                          Progress:(TaskProgress)progress
                            Result:(TaskResult)result{
    /**
     *  创建下载队列，其中"download"为线程标示符
     */
    task_queue("download", ^{
        NSURL *requestUrl = [NSURL URLWithString:url];
        NSURLRequest *request = [NSURLRequest requestWithURL:requestUrl];
        NSURLSessionDownloadTask *task = [[RequestManage shareTaskManage] downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
            //回到主线程
            main_view_queue(^{
                progress(downloadProgress.fractionCompleted,fileName);
            });
            
        } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
            /**
             *  拼接返回路径，并返回给 destination block 块
             *
             *  @param NSCachesDirectory 沙盒中 Caches 的路径
             *  @param NSUserDomainMask  搜索文件的范围
             *  @param YES               是否返回绝对路径 YES 是返回绝对路径 NO 返回相对路径
             *
             *  @return 沙盒中 Caches 的绝对路径
             */
            NSString *cachaPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
            NSString *path = [cachaPath stringByAppendingPathComponent:fileName];
            
            NSURL *fileUrl = [NSURL fileURLWithPath:path];
            
            /*设置文件的存储路径(路径你想怎么设我管不着)*/
            return fileUrl;
            
        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
            BOOL isError = NO;
            if (error) {
                isError = YES;
            }
            else{
                NSLog(@"%@下载完成",fileName);
                
            }
            result(response,isError);
            
        }];
        [task resume];
        /* 这个描述可以当做一个任务的标识，一般需要控制任务是才会使用 */
        task.taskDescription = fileName;
        downloadTask(task);
    });
    
}

- (void)createUploadTaskWithUrl:(NSString *)url
                       WithMark:(NSString *)mark
                       withData:(NSData *)data
                           Task:(UploadTask)uploadTask
                       Progress:(TaskProgress)progress
                         Result:(TaskResult)result{
    //创建上传队列
    task_queue("upload", ^{
        
        NSURL *requestUrl = [NSURL URLWithString:url];
        NSURLRequest *request = [NSURLRequest requestWithURL:requestUrl];
        NSURLSessionUploadTask *task = [[RequestManage shareTaskManage]uploadTaskWithRequest:request fromData:data progress:^(NSProgress * _Nonnull uploadProgress) {
            //回到主线程
            main_view_queue(^{
                progress(uploadProgress.fractionCompleted,task.taskDescription);
                
            });
            
        } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            BOOL isError = NO;
            if (error) {
                isError = YES;
            }
            result(response,isError);
        }];
        [task resume];
        /* 这个描述可以当做一个任务的标识，一般需要控制任务是才会使用 */
        task.taskDescription = mark;
        
    });
}

- (void)uploadVideoWithUrl:(NSString *)url videoPHAsset:(PHAsset *)phAsset Params:(NSDictionary *)params loadingView:(UIView *)loadingView Task:(UploadTask)uploadTask Progress:(TaskProgress)progress Result:(TaskResult)result
{
    PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
    options.version = PHImageRequestOptionsVersionCurrent;
    options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
    
    [MBProgressHUD showHUDAddedTo:loadingView animated:YES];
    
    PHImageManager *manager = [PHImageManager defaultManager];
    [manager requestAVAssetForVideo:phAsset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
        AVURLAsset *avAsset = (AVURLAsset *)asset;
        
        NSURL *dataUrl = avAsset.URL;
        
        NSLog(@"URL:%@", dataUrl);
        
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetMediumQuality];
        NSDateFormatter* formater = [[NSDateFormatter alloc] init];
        [formater setDateFormat:@"yyyy-MM-dd-HH:mm:ss"];
        NSString *mp4Path = [NSHomeDirectory() stringByAppendingFormat:@"/Library/Caches/output-%@.mp4", [formater stringFromDate:[NSDate date]]];
        exportSession.outputURL = [NSURL fileURLWithPath: mp4Path];
        exportSession.outputFileType = AVFileTypeMPEG4;
        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            
            main_view_queue(^{
                [MBProgressHUD hideHUDForView:loadingView animated:YES];
            });

            switch ([exportSession status]) {
                case AVAssetExportSessionStatusFailed:
                {
                    break;
                }
                case AVAssetExportSessionStatusCancelled:
                    
                    break;
                case AVAssetExportSessionStatusCompleted:
                {
                    main_view_queue(^{
                        [MBProgressHUD showLoadingHUDAddedTo:loadingView animated:YES];
                    });
                    
                    task_queue("upload", ^{
                        __block NSURLSessionDataTask * task = [[RequestManage shareHTTPManage]POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
                            NSData *videoData = [NSData dataWithContentsOfFile:mp4Path];
                            [formData appendPartWithFileData:videoData name:@"video" fileName:@"video.mp4" mimeType:@"video/mpeg4"];
                        } progress:^(NSProgress * _Nonnull uploadProgress) {
                            //回到主线程
                            main_view_queue(^{
                                
                                MBProgressHUD *hud = [MBProgressHUD HUDForView:loadingView];
                                hud.progress = uploadProgress.fractionCompleted;
                                if (uploadProgress.fractionCompleted == 1)
                                {
                                    [MBProgressHUD hideHUDForView:loadingView animated:YES];
                                }
                                progress(uploadProgress.fractionCompleted,task.taskDescription);
                                NSLog(@"%f", uploadProgress.fractionCompleted);
                            });
                            
                        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                            
                            main_view_queue(^{
                               [MBProgressHUD hideHUDForView:loadingView animated:YES];
                            });
                            NSLog(@"%@", responseObject);
                            NSInteger code = [[responseObject objectForKey:@"code"] integerValue];
                            result(responseObject,code==0?NO:YES);
                        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                            main_view_queue(^{
                                [MBProgressHUD hideHUDForView:loadingView animated:YES];
                            });

                            result(error,YES);
                        }];
                    });
                    break;
                }
                default:
                    break;
            }
        }];
    }];
}

- (void)uploadImageWithUrl:(NSString *)url WithImage:(UIImage *)image Params:(NSDictionary *)params loadingView:(UIView *)loadingView Task:(UploadTask)uploadTask Progress:(TaskProgress)progress Result:(TaskResult)result
{
    [MBProgressHUD showHUDAddedTo:loadingView animated:YES];

    NSString *formatAPI = [NSString stringWithFormat:@"app/%@.htm?imgType=%ld",url,[[params objectForKey:@"imgType"] integerValue]];
    YFLog(@"\nRequest=====>URL:%@%@",[RequestManage shareHTTPManage].baseURL.absoluteString,formatAPI);
    NSData *data = [UIImage smallTheImageBackData:image];
    task_queue("uploadImage", ^{
        __block NSURLSessionDataTask * task = [[RequestManage shareHTTPManage]POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            [formData appendPartWithFileData:data name:@"file" fileName:@"file.png" mimeType:@"image/png"];
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            //回到主线程
            main_view_queue(^{
                progress(uploadProgress.fractionCompleted,task.taskDescription);
            });
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            [MBProgressHUD hideHUDForView:loadingView animated:YES];

            NSInteger code = [[responseObject objectForKey:@"code"] integerValue];
            result(responseObject,code==0?NO:YES);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [MBProgressHUD hideHUDForView:loadingView animated:YES];

            result(error,YES);
        }];
    });
}
/**
 *  任务队列
 *
 *  @param ^block 在此代码块中创建任务
 */
static void task_queue(char *taskName,void (^block)(void))
{
    /**
     *  为下载任务开辟线程
     *
     *  @param "download"              线程标示符
     *  @param DISPATCH_QUEUE_CONCURRENT 并行队列宏
     *
     */
    dispatch_queue_t queue = dispatch_queue_create(taskName, DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        block();
        
    });
}

/**
 *  回到主线程
 *
 *  @param ^block 需要在主线程执行的代码块
 */
static void main_view_queue(void (^block)(void))
{
    /**
     *  涉及到跟 UI 界面元素相关的操作，需要回到主线程执行相关代码
     */
    dispatch_async(dispatch_get_main_queue(), ^{
        block();
    });

}



@end
